/*
 * settings.c
 *
 *  Created on: Sep 24, 2013
 *      Author: cinus
 */
#include <stdlib.h>
#include <libconfig.h>
#include <assert.h>
#include <string.h>

#include "settings.h"

void loadSettings(settings_tp params, const int8* filename) {
	//read the configuration file
	config_t cfg;
	double value; //must be a double due to how th elibrary works
	int8* topologyFileName;
	int8* trainingAlgorithm;
	size_t strLength;

	config_init(&cfg);

	if (config_read_file(&cfg, filename) != CONFIG_TRUE) {
		fprintf(stderr, "\n%s:%d - %s", config_error_file(&cfg), config_error_line(&cfg), config_error_text(&cfg));
		config_destroy(&cfg);
		params = NULL;
	}

	if (config_lookup_int(&cfg, "seed", &params->seed) != CONFIG_TRUE) {
		fprintf(stderr, "No \"seed\" found in configuration file %s\n", filename);
		params = NULL;
		return;
	}
	if (config_lookup_float(&cfg, "backpropagation.eta", &value) != CONFIG_TRUE) {
		fprintf(stderr, "No \"eta\" found in configuration file %s\n", filename);
		params = NULL;
		return;
	}
	params->eta = value;

	if (config_lookup_float(&cfg, "backpropagation.alpha", &value) != CONFIG_TRUE) {
		fprintf(stderr, "No \"alpha\" found in configuration file %s\n", filename);
		params = NULL;
		return;
	}
	params->alpha = value;

	if (config_lookup_float(&cfg, "resilientbackpropagation.etaPlus", &value) != CONFIG_TRUE) {
		fprintf(stderr, "No \"etaPlus\" found in configuration file %s\n", filename);
		params = NULL;
		return;
	}
	params->etaPlus = value;

	if (config_lookup_float(&cfg, "resilientbackpropagation.etaMinus", &value) != CONFIG_TRUE) {
		fprintf(stderr, "No \"etaMinus\" found in configuration file %s\n", filename);
		params = NULL;
		return;
	}
	params->etaMinus = value;

	if (config_lookup_bool(&cfg, "training.onlineTraining", &params->onlineTraining) != CONFIG_TRUE) {
		fprintf(stderr, "No \"onlineTraining\" found in configuration file %s\n", filename);
		params = NULL;
		return;
	}

	if (config_lookup_int(&cfg, "training.epochsFromMin", &params->maxEpochsFromMinimum) != CONFIG_TRUE) {
		fprintf(stderr, "No \"epochsFromMin\" found in configuration file %s\n", filename);
		params = NULL;
		return;
	}

	if (config_lookup_int(&cfg, "training.maxEpochs", &params->maxEpochs) != CONFIG_TRUE) {
		fprintf(stderr, "No \"maxEpochs\" found in configuration file %s\n", filename);
		params = NULL;
		return;
	}

	if (config_lookup_string(&cfg, "training.algorithm", &trainingAlgorithm) != CONFIG_TRUE) {
		fprintf(stderr, "No \"training.algorithm\" found in configuration file %s\n", filename);
		params = NULL;
		return;
	} else {
		strLength = strlen(trainingAlgorithm) + 1;//adding 1 for the terminating \0 character
		params->algorithm = (int8*) malloc(sizeof(int8) * strLength);
		memcpy(params->algorithm, trainingAlgorithm, sizeof(int8) * strLength);
	}

	if (config_lookup_string(&cfg, "net.topologyFileName", &topologyFileName) != CONFIG_TRUE) {
		fprintf(stderr, "No \"topologyFileName\" found in configuration file %s\n", filename);
		params = NULL;
		return;
	} else {
		strLength = strlen(topologyFileName) + 1;//adding 1 for the terminating \0 character;
		params->topologyFileName = (int8*) malloc(sizeof(int8) * strLength);
		memcpy(params->topologyFileName, topologyFileName, sizeof(int8) * strLength);
	}

	config_destroy(&cfg);
}

void reserveSpaceForSettings(settings_tp src, settings_tp dst) {
	uint32 size;

	size = strlen(src->algorithm)+1;//+1 for the \0 char
	dst->algorithm = (int8*) calloc(sizeof(int8),size);
	size = strlen(src->topologyFileName)+1;//+1 for the \0 char;
	dst->topologyFileName = (int8*) calloc(sizeof(int8),size);

}
void copySettings(settings_tp src, settings_tp dst) {
	dst->alpha = src->alpha;
	dst->eta = src->eta;
	dst->etaMinus = src->etaMinus;
	dst->etaPlus = src->etaPlus;
	dst->maxEpochs = src->maxEpochs;
	dst->maxEpochsFromMinimum = src->maxEpochsFromMinimum;
	dst->onlineTraining = src->onlineTraining;
	dst->seed = src->seed;

	memcpy(dst->algorithm, src->algorithm, strlen(src->algorithm)*sizeof(int8));
	memcpy(dst->topologyFileName, src->topologyFileName, strlen(src->topologyFileName)*sizeof(int8));
}
